#ifndef __MPU6050_SW_H
#define __MPU6050_SW_H

#include "stm32f10x.h"                

/**
 * @brief 软件I2C读写MPU6050
 * 
 */

/*****************************   MPU6050寄存器   *****************************/
/* 出厂相关 */
#define MPU_ACCEL_OFFS_REG          0X06    // accel_offs寄存器,可读取版本号,寄存器手册未提到
#define MPU_PROD_ID_REG             0X0C    // prod id寄存器,在寄存器手册未提到
#define MPU_SELF_TESTX_REG          0X0D    // 自检寄存器X
#define MPU_SELF_TESTY_REG          0X0E    // 自检寄存器Y
#define MPU_SELF_TESTZ_REG          0X0F    // 自检寄存器Z
#define MPU_SELF_TESTA_REG          0X10    // 自检寄存器A

/* 参数配置 */
#define MPU_SAMPLE_RATE_REG		    0X19    // 采样频率分频器
#define MPU_CFG_REG				    0X1A    // 配置寄存器
#define MPU_GYRO_CFG_REG	     	0X1B    // 陀螺仪配置寄存器
#define MPU_ACCEL_CFG_REG		    0X1C    // 加速度计配置寄存器
#define MPU_MOTION_DET_REG		    0X1F    // 运动检测阀值设置寄存器
#define MPU_FIFO_EN_REG			    0X23    // FIFO使能寄存器

/* I2C从机参数 */
#define MPU_I2CMST_CTRL_REG         0X24    // IIC主机控制寄存器
#define MPU_I2CSLV0_ADDR_REG        0X25    // IIC从机0器件地址寄存器
#define MPU_I2CSLV0_REG             0X26    // IIC从机0数据地址寄存器
#define MPU_I2CSLV0_CTRL_REG        0X27    // IIC从机0控制寄存器
#define MPU_I2CSLV1_ADDR_REG        0X28    // IIC从机1器件地址寄存器
#define MPU_I2CSLV1_REG             0X29    // IIC从机1数据地址寄存器
#define MPU_I2CSLV1_CTRL_REG        0X2A    // IIC从机1控制寄存器
#define MPU_I2CSLV2_ADDR_REG        0X2B    // IIC从机2器件地址寄存器
#define MPU_I2CSLV2_REG             0X2C    // IIC从机2数据地址寄存器
#define MPU_I2CSLV2_CTRL_REG        0X2D    // IIC从机2控制寄存器
#define MPU_I2CSLV3_ADDR_REG        0X2E    // IIC从机3器件地址寄存器
#define MPU_I2CSLV3_REG             0X2F    // IIC从机3数据地址寄存器
#define MPU_I2CSLV3_CTRL_REG        0X30    // IIC从机3控制寄存器
#define MPU_I2CSLV4_ADDR_REG        0X31    // IIC从机4器件地址寄存器
#define MPU_I2CSLV4_REG             0X32    // IIC从机4数据地址寄存器
#define MPU_I2CSLV4_DO_REG          0X33    // IIC从机4写数据寄存器
#define MPU_I2CSLV4_CTRL_REG        0X34    // IIC从机4控制寄存器
#define MPU_I2CSLV4_DI_REG          0X35    // IIC从机4读数据寄存器

/* I2C主机状态寄存器 */
#define MPU_I2CMST_STA_REG          0X36

/* 中断寄存器 */
#define MPU_INTBP_CFG_REG           0X37    // 中断/旁路设置寄存器
#define MPU_INT_EN_REG              0X38    // 中断使能寄存器
#define MPU_INT_STA_REG             0X3A    // 中断状态寄存器

/* 加速度计数据寄存器 */
#define MPU_ACCEL_XOUTH_REG         0X3B    // 加速度值,X轴高8位寄存器
#define MPU_ACCEL_XOUTL_REG         0X3C    // 加速度值,X轴低8位寄存器
#define MPU_ACCEL_YOUTH_REG         0X3D    // 加速度值,Y轴高8位寄存器
#define MPU_ACCEL_YOUTL_REG         0X3E    // 加速度值,Y轴低8位寄存器
#define MPU_ACCEL_ZOUTH_REG         0X3F    // 加速度值,Z轴高8位寄存器
#define MPU_ACCEL_ZOUTL_REG         0X40    // 加速度值,Z轴低8位寄存器

/* 温度计数据寄存器 */
#define MPU_TEMP_OUTH_REG           0X41    // 温度值高八位寄存器
#define MPU_TEMP_OUTL_REG           0X42    // 温度值低8位寄存器

/* 陀螺仪数据寄存器 */
#define MPU_GYRO_XOUTH_REG          0X43    // 陀螺仪值,X轴高8位寄存器
#define MPU_GYRO_XOUTL_REG          0X44    // 陀螺仪值,X轴低8位寄存器
#define MPU_GYRO_YOUTH_REG          0X45    // 陀螺仪值,Y轴高8位寄存器
#define MPU_GYRO_YOUTL_REG          0X46    // 陀螺仪值,Y轴低8位寄存器
#define MPU_GYRO_ZOUTH_REG          0X47    // 陀螺仪值,Z轴高8位寄存器
#define MPU_GYRO_ZOUTL_REG          0X48    // 陀螺仪值,Z轴低8位寄存器

/* I2C从机数据寄存器 */
#define MPU_I2CSLV0_DO_REG          0X63    // IIC从机0数据寄存器
#define MPU_I2CSLV1_DO_REG          0X64    // IIC从机1数据寄存器
#define MPU_I2CSLV2_DO_REG          0X65    // IIC从机2数据寄存器
#define MPU_I2CSLV3_DO_REG          0X66    // IIC从机3数据寄存器

/* 其它 */
#define MPU_I2CMST_DELAY_REG        0X67    // IIC主机延时管理寄存器
#define MPU_SIGPATH_RST_REG         0X68    // 信号通道复位寄存器
#define MPU_MDETECT_CTRL_REG        0X69    // 运动检测控制寄存器
#define MPU_USER_CTRL_REG           0X6A    // 用户控制寄存器

/* 电源管理寄存器 */
#define MPU_PWR_MGMT1_REG           0X6B    // 电源管理寄存器1
#define MPU_PWR_MGMT2_REG           0X6C    // 电源管理寄存器2

/* FIFO寄存器 */
#define MPU_FIFO_CNTH_REG           0X72    // FIFO计数寄存器高八位
#define MPU_FIFO_CNTL_REG           0X73    // FIFO计数寄存器低八位
#define MPU_FIFO_RW_REG             0X74    // FIFO读写寄存器

/* 器件ID寄存器 */
#define MPU_DEVICE_ID_REG           0X75

/*****************************   MPU6050从机地址   *****************************/
/* @说明: 如果AD0脚接地,IIC地址为0X68(不包含最低位).
   如果接V3.3,则IIC地址为0X69(不包含最低位). */
#define MPU_ID              0X68         // MPU6050的设备ID号
#define MPU_ADDR            0XD0         // MPU6050的7位地址：0xD0/0xD2
/* AD0默认接GND,所以读写地址为0XD1和0XD0(如果接VCC,则为0XD3和0XD2)
    在标准库中库函数内部会自动将读写位置位，我们只需选择0xD0或0xD2 */

/* MPU6050状态类型 */
typedef enum {
    MPU_ERROR = 11,
    MPU_OK = 0,
    MPU_TimeOut = 22
} MPU_State;

/* MPU6050数据单位类型 */
typedef enum {
    MPU_Deg_S,
    MPU_Rad_S
} MPU_Unit_t;

/* MPU6050类型 */
typedef struct __MPU6050{
    uint8_t devID;          // ID号
    float ax, ay, az;     // 各轴加速度
    float gx, gy, gz;     // 各轴角加速度
    float temp;           // 温度
} MPU6050_t;

/* MPU6050参数配置函数 */
void MPU_Set_Gyro_Fsr(uint8_t fsr);
void MPU_Set_Accel_Fsr(uint8_t fsr);
void MPU_Set_Accel_Fsr(uint8_t fsr);
void MPU_Set_Rate(uint16_t rate);
// void MPU_Set_Fifo(uint8_t sens);

/* MPU6050初始化函数 */
MPU6050_t* MPU_Init();
MPU_State MPU_DeInit(MPU6050_t *MPU);

/* MPU6050数据获取函数 */
uint8_t MPU_GetID();
float MPU_GetTemperature(void);
MPU_State MPU_GetGyro_Raw(int16_t *gx, int16_t *gy, int16_t *gz);  // 获取原始值(16位整型)
MPU_State MPU_GetAccel_Raw(int16_t *ax, int16_t *ay, int16_t *az);
MPU_State MPU_GetGyro(float *gx, float *gy, float *gz, uint8_t unit);// 获取实际值
MPU_State MPU_GetAccel(float *ax, float *ay, float *az);
MPU_State MPU_GetData(MPU6050_t *MPU);

// 获取欧拉角的函数在文件imu_quat.c/h

#endif
